# !/usr/bin/env word
# -*- coding: utf-8 -*-
"""
@Time        : 2020/11/20 09:31
@Author      : Albert Darren
@Contact     : 2563491540@qq.com
@File        : CombinationAndPermutation.py
@Version     : Version 1.0.0
@Description : TODO 实现基本的排列组合应用
@Created By  : PyCharm
"""
import itertools


def permutation(sq: str, r: int):
    """
    返回指定序列的r排列及排列数
    :param sq: 序列
    :param r: 长度r,0<=r<=len(sq)
    :return:所有排列元组的列表和排列数
    """
    if 0 <= r <= len(sq):
        per_list = []
        permutation_obj = itertools.permutations(sq, r)
        for element in permutation_obj:
            per_list.append(element)
        return per_list, sq, r
    else:
        raise Exception("非法,r超出[0,len(sq)]范围")


def combination(sq: str, r: int):
    """
    返回指定序列的r组合及组合数
    :param sq: 序列
    :param r: 长度r
    :return:所有组合元组的列表和组合数
    """
    if 0 <= r <= len(sq):
        com_list = []
        combination_obj = itertools.combinations(sq, r)
        for element in combination_obj:
            com_list.append(element)
        return com_list, sq, r
    else:
        raise Exception("非法,r超出[0,len(sq)]范围")


def complex_combination(items_dict: dict, special_sq: str):
    """
    返回有特殊要求的组合总数
    :param items_dict: 组合项与数量组成键值对的字典
    :param special_sq: 特殊要求的字符串序列
    :return:返回在限制情况下的序列总数
    """
    # 生成特殊要求字符串的字典
    special_count = {key: special_sq.count(key) for key in set(special_sq)}
    for key in special_count.keys():  # 修改组合项与数量组成字典的对应值
        items_dict[key] -= special_count[key]
    values_count = sum(list(items_dict.values()))  # 得到所有组合项数量的和
    combination_count = 1
    for key in items_dict.keys():  # 获得每一个组合项的组合数累乘的结果
        combination_count *= len(list(itertools.combinations(range(values_count), items_dict[key])))
        values_count -= items_dict[key]
    return combination_count


if __name__ == '__main__':
    permutations, str_sq, len_r = permutation("word", 2)
    print("""
{}元素集合{}的{}排列总数为:{}
排列结果:{}""".format(len(str_sq), str_sq, len_r, len(permutations), permutations))
    combinations, str_sq, len_r = combination("word", 2)
    print("""
{}元素集合{}的{}组合总数为:{}
组合结果:{}
""".format(len(str_sq), str_sq, len_r, len(combinations), combinations))
    itemsDict = {"A": 4, "C": 3, "U": 2, "G": 2}
    specialStr = "CAA"
    print("长度为11，含4个A、3个C、2个U和2个G，并以CAA结尾的所有RNA序列总共:{}".format(complex_combination(itemsDict, specialStr)))
